<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>进阶：2、过渡效果</title>
	<script type="text/javascript" src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
	<link href="https://unpkg.com/animate.css@3.5.1/animate.min.css" rel="stylesheet" type="text/css">
	<style type="text/css">
	/**
	 * css class的命名有其规律：
	 * （1）DOM插入激活瞬间会添加的class为：[name]-enter-active
	 * （2）DOM删除激活瞬间会添加的class为：[name]-leave-active、[name]-leave-to
	 */
	.fade-enter-active, .fade-leave-active {
	  transition: opacity .5s
	}
	.fade-enter, .fade-leave-active {
	  opacity: 0
	}	
	/* 可以设置不同的进入和离开动画 */
	/* 设置持续时间和动画函数 */
	.slide-fade-enter-active {
	  transition: all .3s ease;
	}
	.slide-fade-leave-active {
	  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
	}
	.slide-fade-enter, .slide-fade-leave-active {
	  transform: translateX(10px);
	  opacity: 0;
	}	

	.bounce-enter-active {
	  animation: bounce-in .5s;
	}
	.bounce-leave-active {
	  animation: bounce-out .5s;
	}
	@keyframes bounce-in {
	  0% {
	    transform: scale(0);
	  }
	  50% {
	    transform: scale(1.5);
	  }
	  100% {
	    transform: scale(1);
	  }
	}
	@keyframes bounce-out {
	  0% {
	    transform: scale(1);
	  }
	  50% {
	    transform: scale(1.5);
	  }
	  100% {
	    transform: scale(0);
	  }
	}	
	</style>
</head>
<body>
	<div id="app1">
		<h3>单元素/组件的过渡</h3>
		<button v-on:click="show = !show">Toggle</button>
		<transition name="fade">
			<p v-if="show">hello</p>
		</transition>
	</div><br/>

	<div id="app2">
		<h3>CSS过渡</h3>
		<button @click="show = !show">
			Toggle render
		</button>
		<transition name="slide-fade">
			<p v-if="show">hello</p>
		</transition>
	</div><br/>

	<div id="app3">
		<h3>CSS动画</h3>
		<button @click="show = !show">Toggle now</button>
		<transition name="bounce">
			<p v-if="show">Look at me!</p>
		</transition>
	</div><br/>

	<div id="app4">
	  <h3>自定义过渡类名</h3>
	  <button @click="show = !show">
	    Toggle render
	  </button>
	  <transition
	    name="custom-classes-transition"
	    enter-active-class="animated tada"
	    leave-active-class="animated bounceOutRight"
	  >
	    <p v-if="show">hello</p>
	  </transition>
	</div><br/>

	<div id="app5">
		<h3>Javascript钩子</h3>
	  <button @click="show = !show">
	    Toggle
	  </button>
	  <transition
	    v-on:before-enter="beforeEnter"
	    v-on:enter="enter"
	    v-on:leave="leave"
	    v-bind:css="false"
	  >
	    <p v-if="show">
	      Demo
	    </p>
	  </transition>
	</div>	

	<script type="text/javascript">
		// ------------------------ 什么是过渡效果？-------------------------
		// 所谓过渡效果，就是DOM在被插入、更新和移除时的过渡切换效果
		// 随着CSS3和各种丰富的动画js的出现，各种网页应用的过渡效果越来越酷炫
		// 如果你想在自己开发的应用中实现各种过渡效果，可以从以下入手：
		// （1）在 CSS 过渡和动画中自动应用 class
		// （2）可以配合使用第三方 CSS 动画库，如 Animate.css
		// （3）在过渡钩子函数中使用 JavaScript 直接操作 DOM
		// （4）可以配合使用第三方 JavaScript 动画库，如 Velocity.js
		

		// ----------------------- 单元素/组件的过渡 --------------------------
		// （1）过渡的CSS类名
		// 我们并没有指定组件过渡时使用什么类，但是如上面所示在过渡时自动使用了style
		// 里定义的class，可见<transition>标签里过渡使用的类是有命名规则的
		// 会有 4 个(CSS)类名在 enter/leave 的过渡中切换
		// 1.v-enter: 定义进入过渡的开始状态。在元素被插入时生效，在下一个帧移除。
		// 2.v-enter-active: 定义进入过渡的结束状态。在元素被插入时生效，在 transition/animation 完成之后移除。
		// 3.v-leave: 定义离开过渡的开始状态。在离开过渡被触发时生效，在下一个帧移除。
		// 4.v-leave-active: 定义离开过渡的结束状态。在离开过渡被触发时生效，在 transition/animation 完成之后移除。
		// PS.这里的v就是<transition>标签的name属性
		var vm1 = new Vue({
			el: '#app1',
			data: {
				show: true
			}
		}) 

		// (2) CSS过渡
		// 最常用的过渡都是使用CSS过渡
		var vm2 = new Vue({
			el: '#app2',
			data: {
				show: true
			}
		})

		// (3) CSS动画
		var vm3 = new Vue({
			el: '#app3',
			data: {
				show: true
			}
		})

		// (4) 自定义过渡类名
		// 我们可以通过以下特性来自定义过渡类名：
		// enter-class
		// enter-active-class
		// leave-class
		// leave-active-class
		// 他们的优先级高于普通的类名，这有助于我们使用一些第三方CSS动画库
		var vm4 = new Vue({
			el: '#app4',
			data: {
				show: true
			}
		})

		// (5) Javascript钩子
		// 有八个钩子：
		// a.元素出现
		// 		before-enter: 元素出现之前
		// 		enter：元素正在进入
		// 		after-enter：元素进入之后
		// 		enter-cancelled：元素进入取消
		// 
		// b.元素消失
		// 		before-leave: 元素消失之前
		// 		leave: 元素消失中
		// 		after-leave: 元素消失后
		// 		leave-cancelled: 元素消失取消
		// 		
		// 	可以把每个钩子看成一个事件，如果绑定了回调在methods，则对应周期会触发
		// 	// ...
		// methods: {
		//   // --------
		//   // 进入中
		//   // --------
		//   beforeEnter: function (el) {
		//     // ...
		//   },
		//   // 此回调函数是可选项的设置
		//   // 与 CSS 结合时使用
		//   enter: function (el, done) {
		//     // ...
		//     done()
		//   },
		//   afterEnter: function (el) {
		//     // ...
		//   },
		//   enterCancelled: function (el) {
		//     // ...
		//   },
		//   // --------
		//   // 离开时
		//   // --------
		//   beforeLeave: function (el) {
		//     // ...
		//   },
		//   // 此回调函数是可选项的设置
		//   // 与 CSS 结合时使用
		//   leave: function (el, done) {
		//     // ...
		//     done()
		//   },
		//   afterLeave: function (el) {
		//     // ...
		//   },
		//   // leaveCancelled 只用于 v-show 中
		//   leaveCancelled: function (el) {
		//     // ...
		//   }
		// }
		// 
		// PS.当只用 JavaScript 过渡的时候， 在 enter 和 leave 中，回调函数 done 是必须的 。 否则，它们会被同步调用，过渡会立即完成。
		// 	  推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false"，Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
		var vm5 = new Vue({
		  el: '#app5',
		  data: {
		    show: false
		  },
		  methods: {
		    beforeEnter: function (el) {
		      el.style.opacity = 0
		      el.style.transformOrigin = 'left'
		    },
		    enter: function (el, done) {
		      Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
		      Velocity(el, { fontSize: '1em' }, { complete: done })
		    },
		    leave: function (el, done) {
		      Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
		      Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
		      Velocity(el, {
		        rotateZ: '45deg',
		        translateY: '30px',
		        translateX: '30px',
		        opacity: 0
		      }, { complete: done })
		    }
		  }
		})
	</script>
</body>
</html>